#include "RingQueue.hpp"
#include "Task.hpp"
#include <pthread.h>
#include <memory>
#include <ctime>
#include <sys/types.h>
#include <unistd.h>
#include <cstring>

using namespace std;

const char* ops = "+-*/%";

void* consymerRoutine(void* args)
{
    RingQueue<Task>* rq = static_cast<RingQueue<Task>*>(args);
    while(true)
    {
        Task t;
        rq->pop(&t);     // 将资源从共享区拿到私有上下文
        t();             // 计算
        cout << "consymer  done : " << t.formatArg() << t.formatRes() << endl;
        //sleep(1);
    }
}

void* productorRoutine(void* args)
{
    RingQueue<Task>* rq = static_cast<RingQueue<Task>*>(args);
    while(true)
    {
        int x = rand() % 20 + 1;
        int y = rand() % 10 + 1;
        char op = ops[rand() % strlen(ops)];
        Task t(x, y, op);
        rq->push(t);
        cout << "productor done : " << t.formatArg() << "?" << endl;
        //sleep(1);
    }
}

int main()
{
    srand((uint64_t)time(nullptr)+rand());
    RingQueue<Task>* rq = new RingQueue<Task>();
    pthread_t c[3], p[3];
    for(int i = 0; i < 3; i++)
    {
        pthread_create(c + i, nullptr, consymerRoutine, rq);
    }
    for(int i = 0; i < 3; i++)
    {
        pthread_create(p + i, nullptr, productorRoutine, rq);    
    }

    for(int i = 0; i < 3; i++)
    {
        pthread_join(c[i], nullptr);

    }
    for(int i = 0; i < 3; i++)
    {
        pthread_join(p[i], nullptr);
    }


    delete rq;

    return 0;
}